#@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `8  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D8:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D8:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED228 FREE SECTORS COPYING---D1:DISKFIX.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 160ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u8<<  B JKIHiDiELV`L8 8 BLV`LxT}8t8l Lu8hihiHHȱȱL8c !#3`Lu8JJJJ`H 8h`HU}ȩh Q8L8 Z8L8 8L8 8L8 8L8S:@9E:E9H '9 H9I9 8 '9h)0ICV}9D9L8 L :::: :Lr:::IEL[::i:iIIL[:`:i::iX}::L:`L{:w:w: C`L:L: D8:MEM.SAV: 8| 9 '9`L:L: D:DUP.SYS:̩ 8Y} x:ɀL: '9`88 |9Y:X: '9L); D8:DUP.SYS; 8::88 9 '98? :`;WL`; 9Z}Ln; ` :Y;Y;L;L;)} Setting Up ATARI 130XE Ram Disk; 9L; ; -9  [} L;D8:; :9 :Y;LLG d}چن߂ 6 M L섭܂ L 6 K L 6 K ʅ 6 M  e} 6 K 6 K L&ą 6 K ʅ 6 M  6 K!  6ɂ M >L1 f}ʅ 6 K ʅ 6 M  6 K  6ɂ M >L1ͅ 6 K ʅ 6 g} M  6 K  6ɂ M >L1Ѕ 6 K ʅ 6 ؆ M  6 K Ӆ h}6 K ۆ ` Lنچ چن 6 6 À LKنچ 6 `ENTER # i}LOAD #ASM ASM #,#,#,#DOSۆ䝇!"``!"ffLL}OS j}S MAC/65MACRO ASSEMBLER 4.20 (c) 1982 Stephen D. Lawro.I.ELS.ENDI.MACR.END.TITLŠ.PAG.WOR.ERRO.BYT.SBYT.DBYT.E k}N.OP.TA.INCLUD .FLOA.CBYTŻ.LOCA.SE*.JSJMDEINLDLDSTSTCPCPBIBRCLCLCLCLDEDEIN l}INNOPHPHPLPLRTRTSESESETATATSTXTXTYBCBCBEBMBNBPBVBVORANEOADSTLDCMSBASROLSRO% <> m}.DEƽ<><.O.AN.NOԡ.RE .REF.DEF.NOT .AND .OR ,X),,,ةNNOOBEREJECLISX n}REMLISCLISNUؐҐҐɐҐ3''3ϐꐰ'ϐϐĐPKrrurSSTWT~x(æK o}J3bǧrnhw ^~7*C25  榤 XʈHh(@`8x0Pp!Aa p}&Ff Ɍ T :X  ,  C uLЋ - ۢ q}-Hȱ h L(EDIWHATTEXTMODũ5 L(Ҍ` HH`ɛ ۱Lɛ r}L^LH Ɛ ݟ 8 zH %h  c $p əLHL ݟ H %h  s}@ ؐ`H h ٰ եԄL Q Ɉ򅗅 `  C t}Ȋ L0ߩ` 04C L؍l !L؍ u}L;8eHeHL H H`L0󆞥hhL;`ʆL; 0  v}  L L; `` 񒦞` ) %H$H`͒I9Ɛ Ɛ`L ĭs  w}i ů8` @`` ۢB `хѦ򤟱")Q ȱ8e`8`LISԠNEבDE̘FI x}NIJASSAVLOAENTEBLOABSAVNUPRINRE΢REРSIZLOME͠BYŠCРDO TEX ۄ ذ ِЄ y}L ۱$  @L8 @ @ @` ۄЩ Əe Ə  ZڰեLo800  z}8` ۹ɛg+< ۩, @`0" `Ѫ$ɛ @$P ` {}8`ɛ @`0 g8`0 45` ۄ, = @`8`U; =ZZZfZn |}nZ& /# 1D EFGJHIMKL=>A Aλ߻A A @: }}=>@>>8?8679<;ޑ<<;C;?<;< ~}>7;;<;<><;N;?>;<<;<;;B<<>< 0 4 5 # 1u  } $%! 3" 2=_  W @=:q:ߌћݝOƞd6ޕÛipMM/,[]+ }-*/!&^"   ۱Ò ɛ;ė(` -Є 5ɛș IX; @򹋻 @ɛ`旤 };*,0ҪH  h`L ۄЄ  @)++D LT hh ` ۤЄѱ  }>  &𥐪 @ @񊨱ɁȱAх`? [``.8` i L@0:`󙋻ə< }ɛ5)"ȱɛ&)"a{i 'ȱɛ`IȢ8ee͙̘ װL8 }u慓eeeee褚 `8IȄ嚅8圕坕 }嚅馛褚`` . ݟ ȱ "Lsee`Lee` }  g `8` ݟ ȑ "L ,L ݟ "8堨0 }L c S> a з` g S /    "Ll` L  Qڥ }< g Qڠȱ)Ȅ汥 )   UX `Xd ĵB  ] Ķ m  } ` 9;!  ݩLVԩ <0 ̎ H Nԅh ܗL'ՅԅՅօנ&uԕ } JJJJ ϗ) ϗ(L' 0 `$  ꗥHJJJJ h))`Lį`s8 քՊօ }0ȱ8eԐհֱ֤֠H h`J (L ` ) ` ``͌ƵƵƶƶ`mi͝L }H 0+ hȄ H Qڭim hLhH hL˜ H  hH hɛ` S }Ʈ` S  g LݟƐƐLݟ@  SƐ  SAR }{Ɛ 00 N g 0ͥeLyԦH gh g S) S N g$PI L } Įɛʆ N g䮐)`  Lai@( `ș`@  SE*JFH hG }*I%L˚ SJ FH ޚh* S=Lܢ`8qiHH hihi` }H饦 ޚL  LEH h HLܢ WHVH`ajllvp)`8`LLܢ g. };* S  Q ؐ! gͭLv ] ]ҩ; S>+ 8吪8吅膐 LWƐ ] } 8 " ,p   "L`- ? Qک Q L(Y ɛL08҅8HŲ }&eҪȹɛʈıh8宅汥豂Ʈ򅗅 -L^ BL& c 򈄲 }Ʊ洤́汤IJ ـ褳Ȅ` , g S?莁` S)e` m } m } }mL= SB  JLH$ h L L g SN 匥 eLH LH g Z ZL Z }Ze樥e͙ ̘Ѧ o  碈  з` Z7 Z0 Z ZLF Z Z 9 } ZL|L ȟ 8儅充 k  ӍLӷ ȟ ( 8慜煝 k }Lʼnň` š Š``  `ŝ Ŝ` ԥ ݟ $p L( N [б })ȩ Ȅe8Ш ˶ LQڥЯ ˶ L ޶Lԟ搠 ޶  ն L ř Ř } ř Ř` "L` e` }  } g    š Ġ }`Ʈ0ii`   g; L L L` g]; X _ &  gD S; } g+ S; ȟ g / ~ G P n !@ ^ L+ S<` }& { з ޶ii  j H L(  G P:ӄ7 }X҄ۺ;hd~  }` <& S] ߭р SXILLy,PLޚ$0c ^ m )$0O J = ե m $01  }, L۸$ 8 MLL θ)` Ƹ  Ĺ  -(`$0 ` L S i U8`0 } "Ȅ<$0)Hh`H 8嬨孪8h g g0  0 L }v" mHlH`+LD gLv)ㅪ) S?>  @Ɛ eɂ ɀ  }  g g g  Lv  (L9@ L 9L < S ` S 9) - } ܢLLܢ LФȥ LL ư  LܢLФ` L S ) } Lܢ@𥆝i ܢ 0$0 `i e/ }ȑȥȥȄ g>;:=A /L*Ɛ HhȥȥȄiL⥥`L S  Ǭ搦ʩ` }G!@` ܢ`Le H h g g gLv@L搩l S }@)8 <L S`L*) ܢ < ܢ S`8 } E( Ǭ$0). ȥՑL) ȱՆL ) LHH hh` էL }ܢ է Lܢ SA`/0 S)QP S) `    cLܢ Z Z Z Z`L } $LHH ޚ hhLL$ 8`$p/+ߤėLѤė ՚ Ƹ } ਩8 LШL۸ Ĺ  sƗƮ`_<+ 2ԅդ6e  }$Hՙ+ȥԙ+ȄhԅL83+`ų* {LdHH`+L8 L搥 Ɛԥ }ȥ`刾++`(Xȉ9܂e( S0' J搱`LS 1 }`ei` )ȱ` ` S@` 劤шܦ eȪHȱȱ)h`6` }0``Յԩ` ©eԅԘeՅ`8ԅԩՅ` ©8ԅԘՅ`օנ` © FfffԈ0?uؕԅՅ } ©Ն &&&8થ׆Ԉ` ©%ՅՊ%ԅ`$p$0)  몥 Ն` 몥 })Iڤhh+Lshhզ uՆL8 ©ՅՊԅ` ©EՅՊEԅ` ©Ր` ><7 23 +)* ©! }  LL    ) }䯐` ?i??[Z 07ee YzȱĘL8匝 }卝ei͙ ̘L8匑ȥ卑ȪȑȑȩȽ䯐`$P<@4 }!18匝9卝808899莚(` Lӭ )H0 L )ёё hH  h$ }$0 ,P {`? ?ԩL*** ERROR -MEMORY FULBAD DEBRANCH RANGNOT Z PAGE/IMUNDEFINED LAB }EEXP TOO COMPLEDUP LABEO'FLO IF/ENDIF NESTIN VAL >25 IF/ENDIF STAC NESTED MACRO DE PHASE ERRO*= EXP UNDESYNTAX } O'FLODUP MACRO NAMLINE # >6553MISSING .ENDNO *NUM/REN O'FLONESTED INCLUDLIST O'FLONOT SAVE FILLOAD TOO BI }NOT BINARY FILINVALID .SETOO MANY X-REFTOO MANY LOCAL FIELDUNDEFINED MACRMACRO NESTIN BAD PARAMETE!NOT F.P. NO } DEV HANDLE҉TRUNCATED REÊTIMEOUԋNAːWRITE PROTECTEĒBAD DEV CMĠDRIVE TOO MANY OPEN FILEӢDISK FUL̥FILE NAMŧLOCKEĪFIL }E NOT FN(SEE MANUAL$`݆   װLH`H H hh 鸩 R ƥ0C }6ȐH J, h⩮^+ȱ8e;LLa L ͹0L` GA }) 8动勢  * ɇ * *LɆɅɄ $p 6LN`ۺȄ@ J @[ }L 0 0 Ĺ `0עਈɛO(K֠)- Hȱh ץ8 0L }q JL >L(@[` 0 0i~iنؠ0 >օנ֐ֈƮ ȱ֐+Į! }䪱ؑHر֑hֈ֥ЦքׄИ}e`q䨊e`8包卅  0PH }hšĠ答 $0 (,  J8  鸩 Ĺ Lqɇ'IimiLv  LvɆ } LֳɅ LvɄ#Lv`` Z渦 6LN ) `Ԣ儐 }`Z8圅坅 o   L8HI 8` }LKȅ k L搥3 财 Qڠ Ÿh _ &Lܢ Lܢɛ }򈱑 `濥ɀ`8~H m~  h`$0 8 xIiH {h {L } { {ȹ8 {9 {̚ȱ`& Ͷ LMLN= Ȋ ``l 搤搱` Ͷ 0`L }ө ϶HI` `H ҶhH hLJ*K+GHFH`H ƶhL `H ն  } նhJ S)` 0`ɀ/ L˷)Lʎ JLڱ)⭆Ŧ  L( } `Ɉ"% ͶNLM 0L4 ӷ 财@` 緥Ɉ` ն 0` ն }C` ӷΆ`~IHEDBKLV`ՆԈ gȱ80 LQՆ gФб$0 } (` LH shHJJJJ ~h)L0123456789ABCDEF s )LL mL殤 (` L0) `` }) Lװ`͟?)4 Ƹ/HH L ^ hhԩ` է Ƹ ܢ J`L 鸭 }` { Ĺ  J }L Ĺ۠ 8 XhLL` }Ĺ  J }8厪 J"LPAGESYMBOL*** ASSEMBLY ERRORS: BYTES FRE ?=?%?=?ۺ; } } }DOS } ] MAC/65 When entering source lines they must begin with a line number which must be followed by one} space. Then, the second space is the label column. The label must start in this column. The third space after the line nu}mber is the instruction column. Instructions may either start in at least the third column after the line number or at least} one space after the label. The operand may begin anywhere after the instruction, and comments may begin anywhere after the }operand or instruction.e.g.:-10 *=$4000 This tells the program where to assemble the code in memory.20 LABEL LDA #$00 L}oad the accumulator with 0.30 STA $9C40 If there is no label leave 2 spaces after the line number.40 EXIT RTS The end.50 };This is like a REM statement. MAC/65 COMMANDScommand: ASMpurpose: ASeMble source filesusage: ASM }[#file1],[#file2],[#file3],[#file4] ASM will assemble the specified source file and will produce a listing and object code} output. File1 is the source device, file2 is the list device, file3 is the object device, and file4 is a temporary file us}ed to help generate the cross reference listing.Any or all of the four filespec's may be omitted, in which case MAC/65 assu}mes the following default filespec(s) are to be used: file1 - user source memory. file2 - screen editor. file}3 - memory. file4 - none, therefore no cross reference. A filespec (#file1, #file3, etc.) can be omitted by substitut}ing a comma in which case the respective default will be used. For the listing file ONLY, you may use the special form "#-}", to indicate that you do NOT want a listing file at all. Example: ASM #D2:SOURCE,#D:LIST,#D2:OBJECTIn this example}, the source will come from D2:SOURCE, the assembler will list to D:LIST, and the object code will be written to D2:OBJECT.} Example: ASM #D:SOURCE , , #D:OBJECTIn this example, the source will be read from D:SOURCE and the object will be wri}tten to D:OBJECT. The listing will be written to the screen. Example: ASM,,#D:OBJECTIn this example, the source wil}l be read from the memory, the object will be written to D:OBJECT, and the listing will be written on the screen. Examp}le: ASM ,#-This produces what is probably the fastest possible MAC/65 assembly. Source code is read from memory and no li}sting is produced (because of the "#-"). If your program does not contain a ".OPT OBJ" line, this becomes what is essentiall}y simply an error checking assembly. (Though even if you ARE producing object code, the assembly speed is extremely fast.)}Note: If assembling from a "filespec", the source MUST have been a SAVEd file.command: DELpurpose: DELete a line or g}roup of lines from the source/text in memory.usage: DEL lno1 [ ,lno2 ]Examples: DEL 100 deletes on}ly line 100 DEL 200,1300 deletes lines 200 through 1300, inclusivecommand: RENpurpose: RENumber all li}nes in Editor memory.usage: REN [ dcnum1 [ ,dcnum2 ] ] REN renumbers the source lines in memory. If no dcnums are sp}ecified, REN will renumber the program starting at line 10 in increments of 10. REN dcnum1 will renumber the lines starting }at line 10 in increments of dcnum1. REN dcnum1,dcnum2 will renumber starting at line dcnum1 in increments of dcnum2.comma}nd: DOSpurpose: exits from MAC/65 to DOSusage: DOS or CPcommand: LOADpurpose: to reLOAD a previously SAVEd MA}C/65 token file from disk to editor memory.usage: LOAD #filespec [ ,A ]LOAD will clear the user memory befor}e loading from the specified device unless the ",A" parameter is appended.command: SAVEpurpose: SAVEs the internal (to}kenised) form of the user's in-memory text/source to a disk file.usage: SAVE #filespeccommand: LISTpurpose: to li}st the contents of all or part of MAC/65's editor buffer in ASCII (ATASCII) form to a disk or deviceusage: LIS}T [ #filespec, ] [ lno1 [,lno2 ] ] LIST lists the source file to the screen, or device when "#filename" is specified. If }no lnos are specified, listing will begin at the first line in memory and end with the last line in memory. If only lno1 i}s specified, that line will be listed if it is in memory. If lno1 and lno2 are specified, all lines between and including ln}o1 and lno2 will be listed. When lno1 and lno2 are specified, neither one has to be in memory as LIST will search for the fi}rst line in memory greater than or equal to lno1, and will stop listing when the line in memory is greater than lno2. } EXAMPLE: LIST #P: will list the current contents of the editor memory to the P:} (printer) device. EXAMPLE: LIST #D2:TEMP, 1030, 1800 lists only those lin}es lying in the line number range from 1030 to 1800, inclusive, to the } disk file named "TEMP" on disk drive 2.NOTE: The second example points out a method of movin}g or duplicating large portions of text or source via the use of temporary disk files. By suitably RENumbering the in-memory} text before and after the LIST, and by then using ENTER with the Merge option, quite complex movements are possible.comma}nd: ENTERpurpose: allow entry of ASCII (or ATASCII) text file into MAC/65 editor memoryusage: ENTER #files}pec [ (,N) (,A) ]Enter will cause the Editor to get ASCII text from the specified device. ENTER will clear the text area b}efore entering from the filespec. That is any user program in memory at the time the ENTER command is given will be erased.}The parameter "M" (MERGE) will cause MAC/65 to NOT clear the text area before entering from the file, text entered will be m}erged with the text in memory. If a line is entered which has the same line number of a line in memory, the line from the de}vice will overwrite the line in memory.The parameter "A" allows the user to enter un-numbered text from the specified devic}e. The Editor will number the incoming text starting at line 10, in increments of 10.CAUTION: The "A" option will always c}lear the text area before entering from the filespec. You may NOT use "M" in conjunction with the "A" option.command: TE}XTpurpose: allow entry of arbitrary ASCII (ATASCII) text without syntax checking.usage: TEXTTEXT will cle }ar all user source code from memory and put the Editor in the text mode. TEXTMODE may be terminated by the NEW command.co }mmand: ?purpose: makes hexadecimal/decimal conversionsusage: ? ($hxnum) (dcnum) ? is the resident hex/decimal  }decimal/hex converter. Numbers in the range 0-65535 decimal (0000 to FFFF hex) may be converted. Example: ? $1200 wi }ll print =4608 ? 8190 will print =$1FFE MAC/65 DIRECTIVESdirective: .OPTpurpose:  } selects various assembly control OPTions.usage: .OPT option [, [NO] option ...]usage notes:the valid options are a}s follows: LIST ERR EJECT OBJ MLIST CLIST NUM XREFThe .OPT directive allows }the user to control certain functions of the assembly. Generally, coding ".OPT option" will invoke a feature or option, whil}e ".OPT NO option" will "turn off" that same feature.You may use any number of options (or NO options) on a single source l}ine. For example, it is legal to use: .OPT NO LIST, NO XREF, OBJ, ERRThe following are descriptions of the individ}ual options:LIST controls the entire assembly listing. NO LIST turns off all listing except error lines.ERR will} determine if errors are returned to the user in the listing and/or the screen. NO ERR is thus dangerous.EJECT c}ontrols the title and page listing. NO EJECT only turns off the automatic page generation: it has no effect on .P}AGE requests.OBJ determines if the object code is written to the device/memory. NO OBJ is useful during trial assem}blies. OBJ is NECESSARY when the code is to be placed in memory.NUM will auto number the assembly listing instead o}f using the user line numbers. NUM will begin at 100 and increment by 1. NUM is generally not useful except for }final, "pretty" assemblies.MLIST controls the listing of MACRO expansions. NO MLIST will list only the lines within a} Macro expansion which generate object code. MLIST will expand the entire Macro.Note that NO MLIST is extraordinaril}y useful in producing readable listings.CLIST controls the listing of conditional assembly. NO CLIST will not list so}urce lines which are not assembled. CLIST will list all lines within the conditional construct.XREF allows the user,} when a cross reference has been specified in the ASM command line, to control which portions of the source program wil}l be cross referenced during the assembly. Any lines of source code between a .OPT NO XREF and the next succeedi}ng .OPT XREF will not be cross referenced. By combining NO XREF and NO LIST, you can list and cross reference } even extremely large programs in pieces. Or you might use NO XREF to avoid indexing entries out of an INCLUDED fil }e. XREF and NO XREF are useless and inoperative (but do not generate errors) if you have not specified a cross r!}eference file name in the ASM command line.NOTE: Unless specified otherwise by the user, all of the options will assume the"}ir default settings. The default settings for .OPT are: LIST listing is produced ERR erro#}rs are reported EJECT pages are numbered and ejected NO NUM use programmer's line numbers $} MLIST all macro lines are listed CLIST all failed conditionals list XREF continu%}ous cross reference NO OBJ SEE CAUTION !!!!!CAUTION: The OBJ option is handled in a special way: IF assemb&}ling to memory the object default is NO OBJ. IF assembling to a device the object option is OBJ.directive: .INCLUDEpur'}pose: allows one assembly language program to request that another program be included and assembled in-line.u(}sage: .INCLUDE #filespecusage note:this directive should NOT have a label.The .INCLUDE directive causes the assembler)} to begin reading source lines from the specified "filespec". When the end of "filespec" is reached, the assembler will resu*}me reading source from the previous file (or memory).CAUTION: The .INCLUDEd file MUST be properly SAVEd MAC/65 tokenised +}program. It can NOT be a ASCII file.Note: a .INCLUDEd file can not itself contain a .INCLUDE directive. EXAMPLE: ,}.INCLUDE #D:SYSEQU.M65 a ASCII file.Note: a .INCLUDEd file can not itself contain a .INCLUDE directive. EXAMPLE: L$II%A $!$H I$I$I$H! I@I! HH$$$@.}@$I$I$ @ B@   @$I$I$I  H  B!$/}0}$@!$H   @"@@$ !$!$$$$@ $H  1}  @ ! @! I%HB@B$ $H@ H" B@2}$$@  B $$$HHI@  UUURII$HBHI!  "A $ HB" !H3}B H$$ $ $@ !D$ @!! HB@ @@I$H  @4}@ B! HB !@ @ @H@@ HB@"A $ HB" !5}HB HhLGLRLLLLLLS, `LLLLLLLLLyL$L*? kl? z v6}  0$~ \= l LR ՜LR  ~ 柠 i ɛ,/H \LhhA[ բ ՜L8A z7}HyH`Ɵ` ~ ~ ~` V`LhL L L8}LLLLȝLLLLL`LgLmLLLLLLLL2LLL Ɵɛ,/`Ġ (`   9} L  0` 800  ţ`  0 ~ ` _ +-H h+ PLR LRƟ  :}+-Ɵ` г `Lw _  ` } ɀ.H h Lh  ( Ƶhhh`Lw6LwH n. h`}~ ɛ ?} `=2(.)*     HJJJJ h)ii@L $0  `@}LLLLšLҡLߡLLL;LOLLL#L,L ERROR!BUG/65 Version 2.0F}COMMANDIMMMEDIATE CMDPROTECTIONPARAMREGISTERBREAKPOINTPRINTERSYNTAX*** ERROR - MNEMONICOPERANDRANGETOO MANY LABEG}L REFSUNDEFINED - I/O ERROR - = USER RUNBREAK! A X Y SP NV_BDIZC PC INSTRADANASBCBCBEBIBMBH}NBPBRBVBVCLCLCLCLCMCPCPDEDEDEEOINININJMJSLDLDLDLSNOORPHPHPLPLRORORTRTSBSESESESTSTSTI}TATATSTXTXTY**a! 0PpXʈAL BHh("b@`8x  J}      Jx x x x d B x x x x x x x Mx x x x K}x x x f g x x x x x x lx x x x ix x x x c ` x x x x x x Ox x x x jL}x x x x e h x x x x x x nx x x x x x x x Vx ux x x x x wvx x x M}x  x x s rx x x x x Ptx x x x x Z Ux x x x x x Nx x x N}x x x x Y ax x x x x x mx x x x LLLg1= IgjתO}'KbӬ֬HLh 0rp c0hf  V o c0F LӨ_ ƂƃL $ @P} oL! 惥ɛТ` ~` { i YB  ь   tLA` rQ} ~ii i Yg  Ƥ t 奤   Ƥ R}Ƥ t L` # dɛ g?L x ~ i V t`L` r ~ P  S}L 㟢R vLK 0 iLLvD:*.* # ɛ H hɛ gL r 㟩H  ei0Hh LT}` x ` i YqH `hhH(DŋNŊF *&Ɵ u 拱ň恥ТL) U}L `` {~x 扢Ł'ŀ PƄƅ i V}H Vh P PƈƉ`Lh ` SƫPƬ`Lh  `l l R ~ # Z W}S 򥀍eeee H Vh t 0LgLKLc x 89HHl6 L X} @0-1   iL @W : AB ƟH xhH #h Y}  tLgLh c0PN   c053 $ c0$Hhɛ Z}L nLh`AXYSPFLfL@H #7 ` R#Rh v0`  ު g LLh ZR[}LVZRTU 0`XYբ 0`H %hƟ`hhh  @ ~&   ~ \}~ SLKii  Ƴƴ`LlL>LlL]}ð }膖膄 &@Ɵ r &@Lh r &R sۆ 3 r &I 3 ~愢 ^}򚥗Lͳ0Ƅƅ L寢 Lp `hhLL =L` SƚƟ ~ i pƄ_}ƅ` r ~ i  HH ðhh 椥 Ƴ Ʊ쥄 Y` H)? 0H`}) h  h HH`   +37AGKWhy LXYH ,hLY cLXYH c L> ca} X YL c  YLY# LB L ,L L c c` \&& Pȱ`HHHb}Hغi8M 膀M hhhhlhhhhhh)h8hX }lc}H, hL恢 ` #򚅈󚅉 Vцц`Lh @)? vLc)L*Lj d}Ƴei򚥁kLͳH hH Ƴh) ,-Lⲽ,-壟򚥃L첀@L  L  e} LⲥLӲ膂膂LⲮ膂膂L cHhee`JJJJJJ`f} q ӍHHH@LC 0CA g}: 㟢P   o c0  L` u` /+(Ɵ  % E` L q}B%DOS SYSB*)DUP SYSB SRAMDISK COMBy\MAC65 COMBXMAC65 DOCBJ-BUG65 COMBSAMPLE M65BSYSEQU M65BbCPARSE M65B"KERNCODEM65BzKERNEL M65SKERNMAC M65PMGR M65!SCROLL M65B"MEM LIS)dIOMAC LIB 6L  H h ` AL9ȱ02:.)ȱ # `Ŵr}H) 7H惢 VhL惢 V VhС A 柩T  hL; 7s})ђ Ƚ0*ܱ ɛ` Lִ re ,,Ų򦱽93 DHCt}H`xllfflfifiof~` Lִ Lƶ Lƶ G 9 + `聾u}ᥲ ԶHӶH`#'7AAEIMS[l = !Lִ 1 6 6L_ ܩv} 1L =L_ 1L_L: L _ @ # `H L 0 :)LL: w}aZ 0< ִLi慦慩L4H #  x}h`h`H &hH .X0*:A"GƟ u ʸ θL4L:H (5 I0& ) )y} θ L4L:XY, ȊђȄ` I` ` Ɵɛ` ƄƅƄƅ0 0 `0z}``L6+  V膂 ƭ` 6/ L 查 0  ? 0{}  .津 `؅٠ i? "800 8|}&e؅ե ح٥٥؅֥مשԅܩՅ8ׅ0Iک۠څߢ&ߐޑݥɺ}}ՠԑץɺll ~}}h'AA SAMPLE PROGRAM USING IOMAC.LIBAEI>D:SYSEQU.M65>D:IOMAC.LIBI5A [end of equates and librari}es...begin code]A$EK.p;; an arbitrary location8X;B SAMPLEL !AROUND;; skip buffers, etc.VX;`BUFFER j}X;tWMESSAGE1 =A This is a test of the sample program  Type your name here -> A~ A AM1LENGTH MESSAGE1}MESSAGE2 AHi there, AM2LENGTH MESSAGE2X;X; BEGIN ACTUAL CODEX; AROUNDOPEN ===AP:A BPUT }=MESSAGE1=M1LENGTHINPUT =BUFFER PRINT  BPUT =MESSAGE2=M2LENGTHPRINT =BUFFER 3PRINT =AAl}so, we send it to the printer...A BPUT =MESSAGE2=M2LENGTHPRINT =BUFFER(!PRINT =AThat's all folksA2 C}LOSE <:FEIP printer...A BPUT =MESSAGE2=M2LENGTHPRINT =BUFFER(!PRINT =AThat's all folksA2 C#AOSS SYSTEM EQUATES FOR ATARIAX;X; FILE = #DN:SYSEQU.ASMX;X;X; I/O CONTROL BLOCK EQUATES$X;)SAV}EPC ;; SAVE CURRENT ORG+X;.@;;START OF SYSTEM IOCBS3IOCB8X;B-ICHID ;;DEVICE HANDLER IS (SET BY OS)L)ICDN}O ;;DEVICE NUMBER (SET BY OS)VICCOM ;;I/O COMMAND`ICSTA ;;I/O STATUSjICBADR ;;BUFFER ADDRESSt&ICPU}T ;;DH PUT ROUTINE (ADR-1)~ICBLEN ;;BUFFER LENGTHICAUX1 ;;AUX 1ICAUX2 ;;AUX 2ICAUX3 ;;AUX }3ICAUX4 ;;AUX 4ICAUX5 ;;AUX 5ICAUX6 ;;AUX 6X;'IOCBLEN IOCB;;LENGTH OF ONE IOCBX; X; IOC}B COMMAND VALUE EQUATESX;COPN;;OPEN CGBINR;;GET BINARY RECORD CGTXTR;;GET TEXT RECORD CPBINR ;;PUT} BINARY RECORDCPTXTR ;;PUT TEXT RECORD(CCLOSE ;;CLOSE 2CSTAT ;;GET STATUS<X;F7X; DEVICE DEPENDENT COMMAND }EQUATES FOR FILE MANAGERPX;ZCREN ;;RENAMEdCERA!;;ERASEnCPRO#;;PROTECTxCUNP$;;UNPROTECTCPOINT%;;PO}INTCNOTE&;;NOTEX;X; AUX1 VALUES REQD FOR OPENX;OPIN;;OPEN INPUTOPOUT;;OPEN OUTPUTOPUPD ;;O}PEN UPDATEOPAPND ;;OPEN APPENDOPDIR;;OPEN DIRECTORYX;X;X; EXECUTE FLAG DEFINESX;#EXCYES};; EXECUTE IN PROGRESS"+EXCSCR@;; ECHO EXCUTE INPUT TO SCREEN,%EXCNEW;; EXECUTE START UP MODE6$EXCSUP ;; COLD ST}ART EXEC FLAG@X;JX; MISC ADDRESS EQUATESTX;^CPALOC ;; POINTER TO CP/Ah#WARMST;; WAR, START (0=COLD)r#MEMLO};; AVAIL MEM (LOW) PTR|%MEMTOP;; AVAIL MEM (HIGH) PTR1APPMHI;; UPPER LIMIT OF APPLICATION MEMORY%INITADR};; ATARI LOAD/INIT ADR!GOADR;; ATARI LOAD/GO ADR(CARTLOC;; CARTRIDGE RUN LOCATIONCIOV;;CIO ENTRY ADR}EOL;; END OF LINE CHARX;+X; CP/A FUNCTION AND VALUE DISPLACEMSNT#X; (INDIRECT THROUGH CPALOC)X; }IE. (CPALOC),YX;"CPGNFN;; GET NEXT FILE NAME'CPDFDV;; DEFAULT DRIVE (3 BYTES)2CPBUFP ;; CMD BUFF NEXT CHA}R POINTR (1 BYTE)CPEXFL ;; EXECUTE FLAG,CPEXFN ;; EXECUTE FILE NAME (16 BYTES)&)CPEXNP;; EXECUTE NOTE/POINT V}ALUES0CPFNAM!;; FILENAME BUFFER:!RUNLOC=;; CP/A LOAD/RUN ADRD)CPCMDB?;; COMMAND BUFFER (60 BYTES)NCPCMDGOX}X;bSAVEPC;; RESTORE PClX;FER:!RUNLOC=;; CP/A LOAD/RUN ADRD)CPCMDB?;; COMMAND BUFFER (60 BYTES)NCPCMDGOX!/(# 10CPALOC)#X;*#3X; Note that these equates will not be assembled+#-X; if CPALOC has been previously defined,#,X; !} (e.g., if you have .INCLUDEd SYSEQU)-#X;.#/X; Also note that they will not be assembled/#*X; on the second pass of the as!}sembly0##AX; These locations must be accessed indirectly through CPALOC?#"X; i.e.: LDA (CPALOC),Y@#!}X;A#"CPGNFN;; GET NEXT FILE NAMEB#'CPDFDV;; DEFAULT DRIVE (3 BYTES)C#2CPBUFP ;; CMD BUFF NEXT CHAR POINTR (1 BYTE)!}D#CPEXFL ;; EXECUTE FLAGE#,CPEXFN ;; EXECUTE FILE NAME (16 BYTES)F#)CPEXNP;; EXECUTE NOTE/POINT VALUESG#CPFNAM!}!;; FILENAME BUFFERH#RUNLOC=;; CP LOAD/RUN ADRI#)CPCMDB?;; COMMAND BUFFER (60 BYTES)J#,CPGOCMD;; ENTRY POINT FOR D!}O AND MENUK#X;L#;; [ .not .def CPALOC ]M#X;N#*ACPARSE -- OS/A+ command line parserAO#LX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;P#X;Q#' (!}.OUT). These flags are presumed to#EX; be used in future products associated with 'Redirected I/O'.#X;##X;#X; E!}XAMPLE:#END!}.DATABEGIN.DATA;; first,#.Q>;; we need to clear all our flags, etc.#CP.CLRLOOP#'PBEGIN.DATA8;; by zeroing all by!}tes#1;; of the data area#,ICP.CLRLOOP;; (data area is < 128 bytes)#X;#X; now begins the real work#X;#,# QCPALOC!}#*O>CPGNFN;; we are building the address#PCP.GETFN#QCPALOC$O>$1PCP.GETFN;; of the "get file name" rout!}ine$X;$IX; now we reset the filename getting process back to start of cmd line$X;$#%>CPBUFP;; offset to buffer ptr$Q!}>$P@CPALOC7;; now reset$X; $X; $IX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $X; $!X; The!} major loop of CPARSE -- $EX; performed until there are no more file names or flags to get$X;$X;$ CP.LOOP$-%>CPBUF!}P;; the current buffer ptr pointer$"Q@CPALOC7;; buffer offset to A$*PCP.SAVBUFP;; then save it for a nonce$' CP.GETFN;;!} the address we built up$X;$(%>CPBUFP;; the pointer pointer again$5QCP.SAVBUFP;; recover the former buffer ptr value$2!}R@CPALOC7;; did we get more from the CMD line?$FCP.NOMORE;; no...quit now$X;$9X; to here: we got either a filename or !}a set of flags$X;$-%>CPFNAM;; the pointer to the name buffer$X; we scan for the colon$ CP.COLON $ Q@CPALOC7!$R> :;;!} is this the colon?"$FCP.CFND;; yes#$3;; to next char$$ HCP.COLON%$;;; oops...bad command line?&$:;; carry set says 'OO!}PS''$X;($(X; we got the colon...check for flags)$X;*$ CP.CFND+$3,$!Q@CPALOC7;; the possible flag-$R> >;; redirected out!}put?.$ FCP.OUT/$R> <;; redirected input?0$ FCP.IN1$R> -;; flags follow?2$FCP.MINUS;; yes3$R> +;; flags follow?4$FCP.!}PLUS;; yes5$R> 06$DCP.GOFNAM;; not a digig7$ R> 98$ECP.GOFNAM;; not a digit9$QARGC;; is this first arg?:$'FCP.LOOP!};; yes...ignore line number;$X;<$ CP.GOFNAM=$1!CP.FNAM;; if none of those, must be filename>$X;?$%X; CP.NOMORE -- no more!} to process@$X;A$)CP.NOMORE,;; simply go back to callerB$':;; ...with carry clear meaning 'OK'C$&ACPARSE -- process < and!} > flagsAD$X;E$IX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;F$X;G$3X; CP.IN and CP.OUT -- process!} the < and > flagsH$X;I$ CP.INJ$$>FLAG.INFLAG.INOUTK$ !CP.INOUTL$ CP.OUTM$$>FLAG.OUTFLAG.INOUTN$X;O$ CP.INOUTP$!}/QARGC;; we get the current file name numberQ$9PFLAG.INOUT9;; and set the redirection flag as neededR$X;S$FX; now fix up c!}md buffer ptr in case user did '>file' with no spaceT$X;U$3;; to next char followingV$Q@CPALOC7;; get that charW$R> A;; !}is it alpha?X$DCP.IOQUIT;; noY$R> Z;; alpha?Z$ECP.IOQUIT;; no[$HX; next char is alpha, presume it is filename...user !}forgot the space\$$%>CPBUFP;; again, the buffer ptr]$-Q@CPALOC7;; get the current buffer offset^$,_$'O>CPCMDB;; include o!}ffset to buffer`$%?;; make a buffer ptr out of Y rega$1;; back up one charb$X;c$ CP.IOLPd$'Q@CPALOC7;; get a char from cm!}d bufe$R> <;; redirector?f$FCP.ADJUST;; yesg$R> >;; other kind?h$FCP.ADJUSTi$1j$HCP.IOLP;; keep lookingk$X;l$ CP.A!}DJUSTm$3;; back to first alpha charn$Co$;p$,S>CPCMDB;; change from buf ptr to offsetq$!GCP.IOQUIT;; shouldn't happenr$"%!}>CPBUFP;; ptr to offset agains$/P@CPALOC7;; and we have backed up...we hopet$X;u$X;v$ CP.IOQUITw$!!CP.LOOP;; get next p!}arameterx$*ACPARSE -- process the + and - flagsAy$X;z$IX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!};;;{$X;|$7X; CP.MINUS and CP.PLUS -- process '-' and '+' flags}$X;~$ CP.MINUS$Q>;; the 'minus' flag$ HCP.PM$ CP.PL!}US$Q>;; the plus flag$X;$ CP.PM$&LARGC;; include the filename count$X;$9X; now process all legit characters foll!}owing the flag$X;$ CP.PMLP$3;; to next char$5;; save the flag value$/Q@CPALOC7;; get the possible flag character$0!}>;; transfer the character to use it as index$(7;; and recover the flag value to use$(> A;; is it alpha?$&DCP.PMNUM;; no!}...check for numeric$(> Z;; is it alpha$4ECP.PMQUIT;; no...and can't be numeric...so quit$X; if to here, is alpha$+!}PFLAG.A A9;; so set up the proper flag$#DCP.PMLP;; do another character$X;$$X; if here, possible numeric flag$X;$ !}CP.PMNUM$(> 0;; numeric?$DCP.PMQUIT;; no$(> 9;; numeric?$ECP.PMQUIT;; no$)PFLAG.0 09;; yes...so setup the fla!}g$ DCP.PMLP$X;$X; end of flag characters$X;$ CP.PMQUIT$1!CP.LOOP;; another flag or name to do...maybe$#ACPARSE!} -- process a filenameA$X;$IX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;$X;$4X; CP.FNAM -- we!} have a valid filename to process$X;$ CP.FNAM$'QARGC;; get cnt of filenames so far$T?;; double, to use as ptr$>;; .!}..actually as index$QCP.BUFCNT$,$(O>ARG.BUF;; develop address where$%PARGV9;; ...this argument will be$Q>$O!}>ARG.BUF$%PARGV9;; both bytes, of course$X;$.%>CPFNAM;; start of the filename in buffer$/$CP.BUFCNT;; count o!}f characters in ARG.BUF$GX; we move characters from CP's internal buffer to our master buffer$X;$ CP.FNLP$Q@CPALOC7;;!} get a character$5GCP.FNDONE;; presumably, a RETURN ($9B) character$ R>!;; is it a space or less?$DCP.FNDONE;; yes$(P!}ARG.BUF9;; good character...save it$2;; bump counter$3;; and pointer$1)>CPFNAM;; max number of chars we transfer$!}HCP.FNLP;; more to do$X;$BX; if to here, either got a non filename char or moved 15 chars$X;$ CP.FNDONE$Q>$&PAR!}G.BUF9;; ensure good terminator$+2;; to start of next position in ARG.BUF$#&CP.BUFCNT;; for next file name$X;$0#ARGC;;!} and say we have gotten another file!$X;$)!CP.LOOP;; next cmd line name or flag$X;;; for next file name$X;$0#ARGC;; X@!A. KERNEL SUBROUTINESAAX;B)X;************************************CX;D.X; KERNEL CODE -- RAM and coded su%}broutinesE-X; to support kernel macrosFX;G)X;************************************HX;IX; first, RAM usa%}geJX;Kd&}Pe Pf%>g?L1hT?i Uj TkD?L2l,mOnD?L2o #p?L2q1rH?L1sPt Qu P&}v:wX;xX; Divide subroutineyX;z QQRDIV{%>|Q} P~ Q?LA1 TU? R D?LA2 &}S #?LA21 H?LA1PQ> P QPԎ:X;X; Get a single byteX; QQGET T&}16 >Q>PB9Q>PH9PI9 V ERRCHK :X;X; Put a single byteX; QQPUT T16 >&}Q> PB9Q>PH9PI9QQQPASS V ERRCHK :&X; calculate the length of a stringX;X; pri&}nt subroutineX; QQPRECQ> PB9 V ERRCHK :X;,X; print an integer number (PRINUM macro)X; Q&}QPIN ;;I>FP ;; FP>ASCIIQP˾ QP QQSLEN)QQPASS F?NOERR D?NOERR%> !@QQT& }RAP: ?NOERR;QQQPASS SQQLENPQQPASS F?LD3?LD1Q>  PQQPUTBPUT QQPASS=QQPUTB"QQPAS& }S H?LD1?LD3%>?LD2Q@7M> PQQPUTB PUSHY PUT QQPASS=QQPUTB PULLY 3 )QQLEN & }H?LD2:X;X; input subroutineX;QQINQ>PB9 V ERRCHK :X;X; ININUM supporX; QQIN& }INPQQPASSINPUT QQPASS=VPOKE =POKE =  D?NO2ERR !@QQTRAP: ?NO2ERR & } D?NERR2 !@QQTRAP: ?NERR2:X;X; LOAD a file (LOAD macro)X; QQLOADGET =QQPASSGET =QQPA&}SSQQQPASS MQQPASS R> F?LE7 %> !@QQTRAP: ?LE7 GET =QQPASS GET =QQPASS&} GET =QQPASS GET =QQPASS CALC QQPASS MINUS QQPASS PLUS  $>P Q PH9 Q &}PI9 QQQPASS PD9 QQQPASS PE9 Q> PB9  V ERRCHK  &)>;; no error...about to get EOF? &}F?LE8;; yes $!?LE7;; no...get another segment ?LE8CLOSE  : X; X; execute GR subroutine! X;" QQGR# PQQPAS&}S$ CLOSE % QQQPASS& M>' N>( L> ) PQQPASS* +OPEN =QQPASS=QQPASS=AS:A+ :, X;- X&}; execute DRAWTO subroutine. X;/ QQDRAW0 $>`1 Q>2 PB93  V4 ERRCHK 5 :6 X;7 X; execute FILL subroutine8 X&};9 QQFILL: P; $>`< Q>= PB9>  V? ERRCHK @ :A X;B )X; Support for TRAP and error messagesC X;D QQERMSG&} AFatal Error #AE QQERMLEN QQERMSGF QQERRG 'QQENUMH POKE QQENUM=I CR J CR K BPUT =QQERMSG=QQE&}RMLENL PRINUM =QQENUM=M CR N CR O -PRINT APush key to return to DOSAP STOP Q !@ :R X;S X; suppo&}rt for STOP macroT X;U QQSTOPV 6W 5X PUSHX Y PUSHY Z SOUND = = =[ WAIT <\ SOUND ===] ?LF&}6^ Q_ R>` H?LF6a PULLY b PULLX c 7d 8e :f X;g X; support for BMOVE macroh X;i QQBMOVj %>k 'QQPASS&}l 'QQPASSm ?LG1n Q@7o P@7p DINC q DINC r DINC QQPASSs DEQCMP QQPASS=QQPASSt H?LG1u :v &}X;w X; support for PGMOVE macrox X;y QQPGMVz P{ C| 5} %>~ ' 'ր ?LH1 Q@7 P@7 3 H?LH1 7 ?&} : X; X; support for BCLR macro X; QQBCLR C 5 %> 'QQPASS 'QQPASS ?LI1 Q> P@7 DIN&}C ˕ DINC QQPASS DEQCMP QQPASS=QQPASS H?LI1 7 ? : X; 'X; QQSLEN -- find length of a string *X; w&}hich is terminated by a char with X; MSBit on. X; QQSLEN %> ?LB13 Q@7 I?LB1 3 'QQLEN : *X; w$tE;%A. Some pertinent remarksA6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X; KERNEL.M65X;+X*}; System support macros and subroutinesX;(X; This file MUST be .INCLUDEd before*X; any of the other libraries are us* }eX; in your program.X;6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;5X; Notice how we include the macr*!}os ONLY on pass 1%X; of the assembly...thus saving$X; time during the second pass.X;0X; For even greater savings*"}, you may .INCLUDE4X; the separated forms of this file (KERNEL.MAC*X; and KERNCODE.M65) in your own code*X; follo*#}wing the example of COPY1.M65X; 10@@PASS.@@PASS;; this is only equated (defined)$;on pass 1, so all the follo*$}wing#;macros are only read on pass 1X;$A. KERNEL support macrosAX;6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*%};;;;;;;;;;;;;;X;)X; First: a set of support macros used)X; internally by other macros and/or #X; system support s*&}ubroutines. X; 6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; -X; PULLY, PULLX, PUSHX, PUSHY, PHR, PLR --)X;*'} simply save and restore registersX;1X; Note that PHR and PLR are controlled by theX; switch @@PUSHREGS!X;)*(}@@PUSHREGS;; by default, save regsX;X; PULLY 7? PULLX 7> PUSHX A 5!" PUSH*)}Y #C$5%& PLR '@@PUSHREGS( PULLY ) PULLX *+, PHR -@@PUSHREGS. PUSHX / PUSHY 012**}X;38X; BLT and BGT -- only work on certain ranges of args4X;5 BLT 6D 78 BGT 9D@GT:H ;@GT<=X;>*+}.X; PLDA -- load an argument which is either?+X; immediate (if < 256) or an address@X;A PLDA B   CQ D*,}EQ> FGHX;I'X; DCMP, DEQCMP -- used by IF macrosJX;K DCMP LDPOKE QQCMP= MDPOKE QQCMP= N;*-}O QQQCMPP SQQCMPQ QQQCMPR SQQCMPST DEQCMP UDPOKE QQCMP= VDPOKE QQCMP= W QQQCMPX R*.}QQCMPY6Z QQQCMP[ RQQCMP\6]7^ PQQCFLG_7` MQQCFLGa5b8cdX;e3X; SGET -- get a string argument */}which is eitherf/X; literal (in quotes) or an addressgX;h SGET i  j !  k?STR =l Q>4?ST*0}RmPD9n Q>5?STRoPE9pQ>qPI9rQ> sPH9tu Q>4 vPD9w Q>5 xPE9y  zDPOKE QQCMP=*1} { QQQCMP|PH9} QQQCMP~PI9Q>PI9Q>PH9X;(X; T16 -- simply multiply A-r*2}eg by 16X; T16 T?T?T?T?X;1X; ERRCHK -- used by all I/O to implement TRAPX; ERRCHK )>*3} IERRK !@QQTRAP:ERRKX;"X; CHAN -- get a channel numberX; CHAN   Q  T16 > $*4}> X;(X; BPGET -- support for BPUT and BGETX; BPGET  CHAN  Q>5 PE9 Q>4 PD9*5} Q PI9Q PH9Q> PB9 V ERRCHK A. GRAPHICS macrosAX;0X;;;;;;;;;;;;;;;;*6};;;;;;;;;;;;;;;;;;;;;;;;;;;;X;-X; GRAPHICS support macros from KERNEL.M65X;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*7};;;;;;X;X;*X; GR -- same as BASIC GRAPHICS commandX;GR  PHR  PLDA  QQGR PLR X;X;*8} POS -- set X/Y positionX; POS DPOKE U= POKE T= X;4X; COLOR -- choose a COLOR for a later PLO*9}T, etc.X; COLOR POKE QQCOLR= X;X; PLOT -- plot a pointX; PLOT POS = PUT =QQ*:}COLRX;X; SETCOLOR -- same as BASICX;SETCOLOR  PUSHX  PLDA > PLDA  T16 P P*;}LDA ,OP9 PULLX X;+X; LOCATE -- what color is a given pixelX; LOCATE POS =  *<}GET =   X; .X; TXTPOS -- position cursor in text windowX; TXTPOS DPOKE = POKE = *=}X;X; DRAWTO -- draw a lineX; DRAWTO POKE =QQCOLRPOS =  PHR  QQDRAW PLR !X;"$X*>}; FILL -- fill an area (uses OS)#X;$ FILL % PHR & PLDA ' QQFILL( PLR ) "A. Integer MATH Macro*?}sA X; /X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; 2X; The math macros which are part of KERNEL.M65 X; /X;;;;;;;*@};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; X; ,X; CALC -- begin a CALCulation by loading /X; first number into pse*A}udo-register X; CALC DPOKE =   X; 2X; STORE -- store results of a math calculation X; STORE Q*B} P  Q P   X; 1X; PLUS -- add a value from memory to register X; PLUS    , Q> *C} O P D?K # ?K  , Q  O P Q  O P   X; 4X; MINUS -- subtract *D}a value from pseudo-register X; MINUS    ; Q S>  P Q S> P  ; Q S *E} P Q S  P   X; 0X; MUL -- multiply pseudo register by a value X; MUL PUSHY  *F}PLDA  P QQRMUL PULLY   X; .X; DIV -- divide pseudo register by a value X; DIV PUSHY *G}PLDA  P QQRDIV PULLY   X; #X; RND -- choose a random number X; RND  POKE QQCMP=  ?K*H} Q  RQQCMP BGT ?K F?K A. I/O MacrosAX;5X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*I}X;"X; the I/O macros of KERNEL.M65X;5X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;&X; OPEN -- open a file *J}to a channelX; OPEN  PHR  CHAN  PLDA PJ9 PLDA PK9Q>PB9 SGET  V*K} ERRCHK  PLR X;0X; CLOSE -- close a channel (no error check!)X; CLOSE  PHR  CHAN Q> *L}PB9 V PLR X;-X; GET -- get a single byte from a channelX; GET  PHR  PLDA  QQGET*M}P  PLR X;)X; PUT -- put a character to a channelX; PUT POKE QQPASS=  PHR  PLDA *N} QQPUT PLR X;(X; BGET -- get a block from a channelX; BGET  PHR BPGET = = = PLR *O}X;&X; BPUT -- put a block to a channelX; BPUT  PHR BPGET = = =  PLR X;X; PRINT*P} -- print a stringX;*X; first, the macro which does the workX; @@PRINT  PHR  CHAN   SGET *Q} =  SGET  QQPREC PLR X;"X; now, the macro the user seesX; PRINT   @@P*R}RINT =   @@PRINT = @@PRINT = = X;X;$X; CR -- output a CR to a c*S}hannel4X; If no channel given, output to channel 0 X; CR    PUT = PUT =*T}X;)X; CLS -- simply output a clear screen#X; character to channel 0X; CLS PUT =}X;4X; PRIN*U}UM -- print an integer number to a channel.X; within a specified width fieldX; PRINUM  PHR  CALC *V} PLDA   PQQPASS! PLDA "PQQPASS# QQPIN$ PLR %&X;',X; INPUT -- input a string from a channel*W}(X;) INPUT * PHR + CHAN , Q>4 -PD9. Q>5 /PE90  1DPOKE QQCMP= 2 QQQCMP3PH94 Q*X}QQCMP5PI967Q>8PI99Q>:PH9;< QQIN= PLR >?X;@'X; ININUM -- input an integer numberAX*Y};B ININUM C PHR D PLDA E QQININFQGP H QI P J PLR KLX;M+X; BLOAD -- load a binary *Z}file to memoryNX;O BLOAD P PHR Q CLOSE ROPEN === S QQLOADT PLR UA. CONTROL macro*[}sAX;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;&X; The control macros of KERNEL.M65X;0X;;;;;;;;;;;;;;;;;;*\};;;;;;;;;;;;;;;;;;;;;;;;;;X;X;0X; GOSUB -- same as JSR except saves X&Y regsX; GOSUB  PUSHX  PUSHY *]}  PULLY  PULLX X;X; IFEQ, IFNE, IFGT, IFLT --/X; compare two integer values and branchX; if*^} condition is metX; IFEQ DEQCMP =  H@THEN!  @THEN IFNE DEQCMP =  F@THEN! *_} @THEN IFLT DCMP =  I@THEN!  @THEN IFGT DCMP =  I@THEN!  @THEN*`}X;7X; DOI, LOOPI -- loop control using the 'I' variableX; DOI DPOKE QQLOOP= DPOKE QQLOOP= *a}Q>4?K PQQLOOP Q>5?K PQQLOOP ?K LOOPI DINC QQLOOP!IFGT QQLOOP=QQLOOP=@*b}LIQQQLOOP 5QQQLOOP 5:@LIX;7X; DOJ, LOOPJ -- loop control using the 'J' variableX; DO*c}J DPOKE QQLOOP= DPOKE QQLOOP= Q>4?K PQQLOOPQ>5?K PQQLOOP?K LO*d}OPJ DINC QQLOOP$IFGT QQLOOP=QQLOOP=@LJQQQLOOP5QQQLOOP5:@LJX;7X; DOK*e}, LOOPK -- loop control using the 'K' variableX; DOK DPOKE QQLOOP= DPOKE QQLOOP = Q>4?K *f}PQQLOOPQ>5?K PQQLOOP?K LOOPK DINC QQLOOP$IFGT QQLOOP=QQLOOP =@LKQQQ*g}LOOP5QQQLOOP5:@LK TRAP VPOKE QQTRAP= p#A. MISCellaneous macrosAqX;r0X;*h};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sX;t*X; Miscellaneous macros from KERNEL.M65uX;v0X;;;;;;;;;;;;;;;;;;;;;;;;;;*i};;;;;;;;;;;;;;;;;;wX;x(X; DINC -- increment a word (2 bytes)yX;z DINC {# |H?K} # ~?KX;2X; VP*j}OKE -- poke an immediate value into a wordX; VPOKE  Q>4 P  Q>5  P X;+X; DPOKE -- could be*k} better called DMOVEX; DPOKE    Q P  Q  P Q> P Q> P *l}X; X; POKE -- a single byte pokeX; POKE  PLDA P X;.X; WAIT -- wait a certain number of jif*m}fiesX; WAIT POKE  = ?KQ H?KX;(X; STOP -- stop until START is pushedX; STOP  *n}QQSTOPX;&X; SOUND -- just like BASIC's soundX; SOUND POKE =Q>PҶP2   $> *o}  PLDA T?> 2 Q>   PLDA  T16 P PLDA M>L*p}P9 PLDA P9X;%X; BMOVE -- move a block of memoryX; BMOVE VPOKE QQPASS= VP*q}OKE = VPOKE =  QQBMOVX;9X; PGMOVE -- special move of a single page (256 bytes)X; PGMOVE *r}POKE =  PLDA  QQPGMVX;3X; BCLR -- clear (set to zero) a block of memoryX; BCLR VPOKE =*s} VPOKE QQPASS=  QQBCLRX;-X; PGCLR -- fast clear of a page of memoryX;X; PGCLR  PUSHY *t}POKE = POKE =??L1P@73H?L1 PULLY XX;b1X; End of all macros -- so end of the .I*u}F froml2X; line 1022 at the beginning of this listingvX;@!A. KERNEL SUBROUTINESAAX;B)X;******************v}*******************CX;D.X; KERNEL CODE -- RAM and coded subroutinesE-X; to support kernel macrosFX;G)X;*w}************************************HX;IX; first, RAM usageJX;KdPe Pf%>g?L1hT?i Uj TkD?L2l,m*|}OnD?L2o #p?L2q1rH?L1sPt Qu Pv:wX;xX; Divide subroutineyX;z QQRDIV{%>|Q*}}} P~ Q?LA1 TU? R D?LA2 S #?LA21 H?LA1PQ> P Q*~}PԎ:X;X; Get a single byteX; QQGET T16 >Q>PB9Q>PH9PI9 V ERRCHK *}:X;X; Put a single byteX; QQPUT T16 >Q> PB9Q>PH9PI9QQQPASS V ER*}RCHK :&X; calculate the length of a stringX;X; print subroutineX; QQPRECQ> PB9 V ERRCHK *}:X;,X; print an integer number (PRINUM macro)X; QQPIN ;;I>FP ;; FP>ASCIIQP˾ QP*} QQSLEN)QQPASS F?NOERR D?NOERR%> !@QQTRAP: ?NOERR;QQQPASS SQQLENPQQPASS F?LD*}3?LD1Q>  PQQPUTBPUT QQPASS=QQPUTB"QQPASS H?LD1?LD3%>?LD2Q@7M> PQQPUTB*} PUSHY PUT QQPASS=QQPUTB PULLY 3 )QQLEN H?LD2:X;X; input subroutineX;QQINQ>PB*}9 V ERRCHK :X;X; ININUM supporX; QQININPQQPASSINPUT QQPASS=VPOKE =P*}OKE =  D?NO2ERR !@QQTRAP: ?NO2ERR  D?NERR2 !@QQTRAP: ?NERR2:X;X; LOAD a file (LOAD*} macro)X; QQLOADGET =QQPASSGET =QQPASSQQQPASS MQQPASS R> F?LE7 %> *} !@QQTRAP: ?LE7 GET =QQPASS GET =QQPASS GET =QQPASS GET =QQPASS CALC QQPASS *}MINUS QQPASS PLUS  $>P Q PH9 Q PI9 QQQPASS PD9 QQQPASS PE9 Q> PB*}9  V ERRCHK  &)>;; no error...about to get EOF? F?LE8;; yes $!?LE7;; no...get another segment ?LE8CLOSE *} : X; X; execute GR subroutine! X;" QQGR# PQQPASS$ CLOSE % QQQPASS& M>' N>( L> ) PQQPASS*}* +OPEN =QQPASS=QQPASS=AS:A+ :, X;- X; execute DRAWTO subroutine. X;/ QQDRAW0 $>`1 Q>2 PB9*}3  V4 ERRCHK 5 :6 X;7 X; execute FILL subroutine8 X;9 QQFILL: P; $>`< Q>= PB9>  V? ERRCHK @ :A*} X;B )X; Support for TRAP and error messagesC X;D QQERMSG AFatal Error #AE QQERMLEN QQERMSGF QQERRG 'QQENUMH *}POKE QQENUM=I CR J CR K BPUT =QQERMSG=QQERMLENL PRINUM =QQENUM=M CR N CR O -PRINT APush *} key to return to DOSAP STOP Q !@ :R X;S X; support for STOP macroT X;U QQSTOPV 6W 5X PUSHX Y PUSHY Z *}SOUND = = =[ WAIT <\ SOUND ===] ?LF6^ Q_ R>` H?LF6a PULLY b PULLX c 7d 8e :f X;g*} X; support for BMOVE macroh X;i QQBMOVj %>k 'QQPASSl 'QQPASSm ?LG1n Q@7o P@7p DINC q DINC r *}DINC QQPASSs DEQCMP QQPASS=QQPASSt H?LG1u :v X;w X; support for PGMOVE macrox X;y QQPGMVz P{ C| 5} *}%>~ ' 'ր ?LH1 Q@7 P@7 3 H?LH1 7 ? : X; X; support for BCLR macro X; QQBCLR C 5 *}%> 'QQPASS 'QQPASS ?LI1 Q> P@7 DINC ˕ DINC QQPASS DEQCMP QQPASS=QQPASS H?LI1 7*} ? : X; 'X; QQSLEN -- find length of a string *X; which is terminated by a char with X; MSBit on. X; QQSLE*}N %> ?LB13 Q@7 I?LB1 3 'QQLEN : *X; which is terminated by a char with X; MSBit on. X; QQSLE(4u(%A. Some pertinent remarksA6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X; KERNMAC.M65X;.}X; System support macrosX;(X; This file MUST be .INCLUDEd before*X; any of the other libraries are useX; in you.}r program.X;6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X;#A. KERNEL support macrosAX;6X;;.};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;)X; First: a set of support macros used)X; internally by other mac.}ros and/or #X; system support subroutines. X; 6X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; -X; PULLY, PUL.}LX, PUSHX, PUSHY, PHR, PLR --)X; simply save and restore registersX;1X; Note that PHR and PLR are controlled by the.}X; switch @@PUSHREGS!X;)@@PUSHREGS;; by default, save regsX;X; PULLY 7? PULLX 7>.} PUSHX A 5!" PUSHY #C$5%& PLR '@@PUSHREGS( PULLY ) PULLX *+, PHR -@@PUSHREG.}S. PUSHX / PUSHY 012X;38X; BLT and BGT -- only work on certain ranges of args4X;5 BLT 6D 78 BGT.} 9D@GT:H ;@GT<=X;>.X; PLDA -- load an argument which is either?+X; immediate (if < 256) or an address@X.};A PLDA B   CQ DEQ> FGHX;I'X; DCMP, DEQCMP -- used by IF macrosJX;K DCMP LDPOKE QQC.}MP= MDPOKE QQCMP= N;O QQQCMPP SQQCMPQ QQQCMPR SQQCMPST DEQCMP UDPOKE QQCMP= V.}DPOKE QQCMP= W QQQCMPX RQQCMPY6Z QQQCMP[ RQQCMP\6]7^ PQQCFLG_7` MQQCFLGa5b8cdX;e.}3X; SGET -- get a string argument which is eitherf/X; literal (in quotes) or an addressgX;h SGET i  j .}!  k?STR =l Q>4?STRmPD9n Q>5?STRoPE9pQ>qPI9rQ> sPH9tu Q>4 vPD9w Q>5 x.}PE9y  zDPOKE QQCMP= { QQQCMP|PH9} QQQCMP~PI9Q>PI9Q>PH9.}X;(X; T16 -- simply multiply A-reg by 16X; T16 T?T?T?T?X;1X; ERRCHK -- used by all I/O to imple.}ment TRAPX; ERRCHK )> IERRK !@QQTRAP:ERRKX;"X; CHAN -- get a channel numberX; CHAN  .} Q  T16 > $> X;(X; BPGET -- support for BPUT and BGETX; BPGET  CHAN .} Q>5 PE9 Q>4 PD9 Q PI9Q PH9Q> PB9 V ERRCHK A. GRAPHIC.}S macrosAX;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;-X; GRAPHICS support macros from KERNEL.M65X;0X;;;;.};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X;*X; GR -- same as BASIC GRAPHICS commandX;GR  PHR  PLDA .} QQGR PLR X;X; POS -- set X/Y positionX; POS DPOKE U= POKE T= X;4X; COLOR.} -- choose a COLOR for a later PLOT, etc.X; COLOR POKE QQCOLR= X;X; PLOT -- plot a pointX; PL.}OT POS = PUT =QQCOLRX;X; SETCOLOR -- same as BASICX;SETCOLOR  PUSHX  PLDA >.} PLDA  T16 P PLDA ,OP9 PULLX X;+X; LOCATE -- what color is a given pixel.}X; LOCATE POS =  GET =   X; .X; TXTPOS -- position cursor in text windowX; TXTPOS DPO.}KE = POKE = X;X; DRAWTO -- draw a lineX; DRAWTO POKE =QQCOLRPOS =  PHR.}  QQDRAW PLR !X;"$X; FILL -- fill an area (uses OS)#X;$ FILL % PHR & PLDA ' QQFILL( PLR ).} "A. Integer MATH MacrosA X; /X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; 2X; The math macros which are .}part of KERNEL.M65 X; /X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; X; X; ,X; CALC -- begin a CALCulation by loading.} /X; first number into pseudo-register X; CALC DPOKE =   X; 2X; STORE -- store results of a math.} calculation X; STORE Q P  Q P   X; 1X; PLUS -- add a value from memory to register X; .} PLUS    , Q>  O P D?K # ?K  , Q  O P Q  O P .}  X; 4X; MINUS -- subtract a value from pseudo-register X; MINUS    ; Q S>  P Q.} S> P  ; Q S  P Q S  P   X; 0X; MUL -- multiply pseudo register by a.} value X; MUL PUSHY  PLDA  P QQRMUL PULLY   X; .X; DIV -- divide pseudo register by a .}value X; DIV PUSHY PLDA  P QQRDIV PULLY   X; #X; RND -- choose a random number X; .} RND  POKE QQCMP=  ?K Q  RQQCMP BGT ?K F?K A. I/O MacrosAX;5X;;;;;;;;;;;;;;;;;;.};;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;"X; the I/O macros of KERNEL.M65X;5X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.};;;X;&X; OPEN -- open a file to a channelX; OPEN  PHR  CHAN  PLDA PJ9 PLDA PK9.}Q>PB9 SGET  V ERRCHK  PLR X;0X; CLOSE -- close a channel (no error check!)X; CL.}OSE  PHR  CHAN Q> PB9 V PLR X;-X; GET -- get a single byte from a channelX; GET .} PHR  PLDA  QQGETP  PLR X;)X; PUT -- put a character to a channelX; PUT POKE QQ.}PASS=  PHR  PLDA  QQPUT PLR X;(X; BGET -- get a block from a channelX; BGET  PHR .}BPGET = = = PLR X;&X; BPUT -- put a block to a channelX; BPUT  PHR BPGET = = .}=  PLR X;X; PRINT -- print a stringX;*X; first, the macro which does the workX; @@PRINT  PHR.}  CHAN   SGET =  SGET  QQPREC PLR X;"X; now, the macro the user sees.}X; PRINT   @@PRINT =   @@PRINT = @@PRINT = = X;.}X;$X; CR -- output a CR to a channel4X; If no channel given, output to channel 0 X; CR    PUT .}= PUT =X;)X; CLS -- simply output a clear screen#X; character to channel 0X; CLS.} PUT =}X;4X; PRINUM -- print an integer number to a channel.X; within a specified width field.}X; PRINUM  PHR  CALC  PLDA   PQQPASS! PLDA "PQQPASS# QQPIN$ PLR %&X;',X; INPU.}T -- input a string from a channel(X;) INPUT * PHR + CHAN , Q>4 -PD9. Q>5 /PE90  1DPOK.}E QQCMP= 2 QQQCMP3PH94 QQQCMP5PI967Q>8PI99Q>:PH9;< QQIN= PLR >?X;@'X; INI.}NUM -- input an integer numberAX;B ININUM C PHR D PLDA E QQININFQGP H QI P J PLR K.}LX;M+X; BLOAD -- load a binary file to memoryNX;O BLOAD P PHR Q CLOSE ROPEN === S QQLOADT P.}LR UA. CONTROL macrosAX;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;&X; The control macros of KER.}NEL.M65X;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X;0X; GOSUB -- same as JSR except saves X&Y regsX;.} GOSUB  PUSHX  PUSHY   PULLY  PULLX X;X; IFEQ, IFNE, IFGT, IFLT --/X; compare two int.}eger values and branchX; if condition is metX; IFEQ DEQCMP =  H@THEN!  @THEN IFNE .}DEQCMP =  F@THEN!  @THEN IFLT DCMP =  I@THEN!  @THEN IFGT DCMP.} =  I@THEN!  @THENX;7X; DOI, LOOPI -- loop control using the 'I' variableX; DOI DPOKE Q.}QLOOP= DPOKE QQLOOP= Q>4?K PQQLOOP Q>5?K PQQLOOP ?K LOOPI DINC QQL.}OOP!IFGT QQLOOP=QQLOOP=@LIQQQLOOP 5QQQLOOP 5:@LIX;7X; DOJ, LOOPJ -- loop control .}using the 'J' variableX; DOJ DPOKE QQLOOP= DPOKE QQLOOP= Q>4?K PQQLOOPQ>5?K.} PQQLOOP?K LOOPJ DINC QQLOOP$IFGT QQLOOP=QQLOOP=@LJQQQLOOP5QQQLOOP.}5:@LJX;7X; DOK, LOOPK -- loop control using the 'K' variableX; DOK DPOKE QQLOOP= D.}POKE QQLOOP = Q>4?K PQQLOOPQ>5?K PQQLOOP?K LOOPK DINC QQLOOP$IFGT.} QQLOOP=QQLOOP =@LKQQQLOOP5QQQLOOP5:@LK TRAP VPOKE QQTRAP= p#A. .} MISCellaneous macrosAqX;r0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sX;t*X; Miscellaneous macros from KERNEL.M65u.}X;v0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wX;x(X; DINC -- increment a word (2 bytes)yX;z DINC {# |H?.}K} # ~?KX;2X; VPOKE -- poke an immediate value into a wordX; VPOKE  Q>4 P  Q>5  P .}X;+X; DPOKE -- could be better called DMOVEX; DPOKE    Q P  Q  P Q.}> P Q> P X; X; POKE -- a single byte pokeX; POKE  PLDA P X;.X; WA.}IT -- wait a certain number of jiffiesX; WAIT POKE  = ?KQ H?KX;(X; STOP -- stop until S.}TART is pushedX; STOP  QQSTOPX;&X; SOUND -- just like BASIC's soundX; SOUND POKE =Q>.}PҶP2   $>   PLDA T?> 2 Q>   PLDA  T16 .}P PLDA M>LP9 PLDA P9X;%X; BMOVE -- move a block of memoryX; BMOV.}E VPOKE QQPASS= VPOKE = VPOKE =  QQBMOVX;9X; PGMOVE -- special move of a single pag.}e (256 bytes)X; PGMOVE POKE =  PLDA  QQPGMVX;3X; BCLR -- clear (set to zero) a block of m.}emoryX; BCLR VPOKE = VPOKE QQPASS=  QQBCLRX;-X; PGCLR -- fast clear of a page of memo.}ryX;X; PGCLR  PUSHY POKE = POKE =??L1P@73H?L1 PULLY a page of memo,o QQVBVR bQQHTM QQHTP  QQVM  QQHP  QQVP QQOVP QQPBAS  QQMBAS 2}QQPFLG  QQMFLG QQSHAP QQPSAV  QQHT QQMASK = =0= QQSMSZ 9QQMSM ===2}========@== =0=QQMBIT === PLDX   $> $  PMGR  PH2}R  PLDA  QQPMGR PLR  SETVEC VPOKE QQVBVR=    SHAPE  PUSHX  PLDA  T?> Q2}>5 PQQSHAP9 Q>4  PQQSHAP9 PULLX  PMCOLR  PUSHX  PLDX  PLDA  T16  PQQCMP2} PLDA , OQQCMPP9 PULLX ! PMOVE " PUSHX # PLDX $ PLDA % PQQHP9& PLDA ' P2}QQVP9(Q>) PQQPFLG9* PULLX +, MMOVE - PUSHX . PLDX / PLDA 0P91 PLDA 2 PQQVM93Q>2}4 PQQMFLG5 PULLX 67 PSIZE 8 PUSHX 9 PLDX :0;A< PLDX =P9> PLDA ? PQQHTP9@ PULLX 2}AB MSIZE C PUSHX D PLDX E0FAGT?HT?I PQQCMPJ PLDA K,L OQQCMPM>N QQQMSM9O LQQSMSZP P2}QQSMSZQP R PLDX S PLDA T PQQHTM9U PULLX VW MPLC X&Y PLDX Z QQQMBIT9[ PLDX \M2}9]5^$_7`a MPFC b&c PLDX d QQQMBIT9e PLDX fM9g5h$i7jk PPLC l&m PLDX2} n QQQMBIT9o PLDX pM 9q5r$s7tu PPFC v&w PLDX x QQQMBIT9y PLDX zM9{5|$2}}7~)X;************************************X; PMGR RUNTIME CODE)X;************************************2} QQPMGRPԅ,O>> PQQMBAS2 &QQPBAS2&QQPBAS2&QQPBAS2&QQPBASQ>P2}ГQ>>P/Q> %>4QQAPMM $>5QQAPMM \: QQAPMM%>?AL1Q8 PQQPSAV83)> H?AL12}$>?AL2 QQQHP9P9 QQQOVP9 RQQVP9 FQQNPX QQQPFLG9 FQQNPX QQQPBAS9Pέ QQQOVP9Pͯ QQ2}QHTP9 PQQHT%>C?AL3P@73 )QQHT H?AL3AT?? QQQSHAP8P˽QQQSHAP8P̿ QQQVP92}P PQQOVP9%>?AL4Q@7P@73 )QQHT H?AL4 QQNPX2(> H?AL2 QQQMFLG FQQRET Q2}QQMBASPQ>P??AL8P@73 H?AL8$>?AL5 QQQHTM9 PQQHT QQQVM9P%>?AL62}Q@7 LQQMASK9P@73 )QQHT H?AL62(> H?AL5 QQRET$>?AL7 QQQPSAV9P9Q> PQ3}QMFLG PQQPFLG92(> H?AL7 !@QQVBVR:2(> H?AL5 QQRET$>?AL7 QQQPSAV9P9Q> PQ02X;/X; The fine scroll macro library and support5X; subroutines. They are heavily interdependent,X; so must 7}always be .INCLUDEd togetherX; XDIM  YDIM  SCRBAS  CSRBAS  SDSPL  SHSROL  SVSROL  HS7}PEED  VSPEED  X0LIM  Y0LIM  LINES  JMPBYT  RVBIV  XLOC  YLOC  CWIDE  CHIGH 7} MLINES  SRBYTW  DIR  HCOUNT  VCOUNT  SCROLL  MODE 0OLDVBV ;; Will hold previous vb7}lank vector'VVBLKD$;; Deferred vblank vector0SETVBV\;; OS routine to set vblank vector X;  SCRDIM  PLDA 7}  > L>p PJMPBYT00 &MODEPOKE XDIM= POKE YDIM= VPOKE SCRBAS= VPOKE SDSPL= 7} QQDSRL SETXY POKE XLOC= POKE YLOC=  QQSXYSTOPSCROLL $OLDVBV %OLDVBV Q>!7} SETVBV"#QQCWID =====$QQCHIG = ====%QQMLIN === == & QQDSRL'DPOKE CSRBA7 }S=SCRBAS( $MODE) QQQCWID9* PCWIDE+ QQQCHIG9, PCHIGH- QQQMLIN9. PMLINES/Q>0 PXLOC1 PYLOC2 PVSPEED3 P7 }HSPEED4Q>5 PSCROLL6Q>7 PSHSROL8 PSVSROL9 QCWIDE:>;Q><(>= HQQSL2>V?? QQSL2@V?AV?B PSRBY7 }TWC QXDIMD;E SSRBYTWF PX0LIMG "X0LIMH QYDIMI;J SMLINESK PY0LIML "Y0LIMM QMLINESNT?O,P OMLINESQ P7 }LINESR #LINESS #LINEST #LINESU$X; WRITE BEGINING & END OF D LISTVDPOKE =SDSPLWQ>pX%>YP@7Z3[P@7 }7\3]P@7^ %LINES_3`3a3bQ>BcP@7d3eQfP@7g3hQiP@7jQ>k3lP@7m3nP@7o3p7}P@7qQ>Ar3sP@7t QSDSPLu3vP@7w QSDSPLx3yP@7zDPOKE RVBIV=${3DPOKE OLDVBV=VVBLKD;; Sav7}e old vblank vector| %>4QQAUTS} $>5QQAUTS~Q> SETVBV;; SETVBVQ>P QQSL3Q HQQSL3DPOKE 07}=SDSPLQ>P: QQAUTSX; SAVE 212 & 204 ON STACK-Qԍ5 Q5Q̑5 Q5DPOKE7} =CSRBASDPOKE =SDSPL%> QQTL1 QJMPBYTP@73QԜP@73 QP@7X; ADD XDIM TO 217}2,Qԣ OXDIMPԥ QO> P3 )LINES HQQTL1X; WRITE LAST MODE LINE QJMPBYTM>WP@7}73QԱP@73 QP@7X; WRITE SHADOWS QSHSROLP;; HSCROL QSVSROLPԺ7 P77}P̾7 P7P QSCROLLPDIRVDIREQQTNU;; NO UPWARD SCROL #VCOUNT QVSPEED RVCOUNT EQQTNU7}Q> PVCOUNT "SVSROL IQQTNU QYLOC HQQTASNQ> PSVSROL FQQTNU QQTASN QCHIGH PSVSROL "YLO7}C; QCSRBAS SXDIM PCSRBAS EQQTNU"CSRBAS QQTNU X; DOWN ?VDIR EQQTNV #VCOUNT QVSPEED R7}VCOUNT EQQTNVQ> PVCOUNT #SVSROL QCHIGH RSVSROL EQQTNVX; CHECK LIMIT QYLOC RY0LIM HQQTASN27} QCHIGH PSVSROL HQQTNV QQTASN2Q> PSVSROL #YLOC, QCSRBAS OXDIM PCSRBAS DQQTNV#CSRBAS7} QQTNV X; LEFT?VDIR EQQTNL #HCOUNT QHSPEED RHCOUNT EQQTNLQ> PHCOUNT #SHSROL QCWIDE7} RSHSROL  EQQTNL X; CHECK LIMIT  QXLOC  HQQTASN3  QCWIDE PSHSROL HQQTNL QQTASN3Q> PSHSROL "XLO7}C "CSRBASQ> RCSRBAS HQQTNL"CSRBAS QQTNL X; RIGHT ?VDIR EQQTNR #HCOUNT QHSPEED RHCOU7}NT  EQQTNR!Q>" PHCOUNT# "SHSROL$ IQQTNR%X; CHECK LIMIT& QXLOC' RX0LIM( HQQTASN4)Q>* PSHSROL+ FQQT7}NR, QQTASN4- QCWIDE. PSHSROL/ #XLOC0 #CSRBAS1 DQQTNR2#CSRBAS3 QQTNR4 !@RVBIV:5 QQSXY6 QX0LIM7 RXL7}OC8BGT QQSX19 PXLOC: QQSX1; QY0LIM< RYLOC=BGT QQSX2> PYLOC? QQSX2@DPOKE CSRBAS=SCRBASA %YLOCB 7}FQQSXL6C QQSXL4D,E QCSRBASF OXDIMG PCSRBASH DQQSXL5I#CSRBASJ QQSXL5K1L HQQSXL4M QQSXL6NX; ADD IN7 } XLOCO,P QCSRBASQ OXLOCR PCSRBASS DQQSXL7T#CSRBASU QQSXL7VX; CLEAR SHADOWSWQ>X PSHSROLY PSVSROLZ7!}7!@OLDVBV:;; Exit through old vertical blank vector.#CSRBASU QQSXL7VX; CLEAR SHADOWSWQ>X PSHSROLY PSVSROLZ4510 .OPT NOLIST0980 .OPT NOEJECT0990 .TITLE "A sample device driver for Atari's OS"1000 .PAGE "--- general remarks -;#}--"1010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1020 ;1030 ; The "M:" driver --1040 ; Using memory as a device1050 ;1060 ; In;$}cludes installation program1070 ;1080 ; Written by Bill Wilkinson1090 ; for January, 1982, COMPUTE!1100 ;1110 ;;;;;;;;;%};;;;;;;;;;;;;;;;;;;;;;;1120 ;1130 ; EQUATES INTO ATARI'S OS, ETC.1140 ;1150 ICAUX1 = $34A ; The AUX1 byte of IOCB1160 ;;&}1170 OPOUT = 8 ; Mode 8 is OPEN for OUTPUT1180 ;1190 MEMLO = $2E7 ; pointer to bottom of free RAM1200 MEMTOP = $2E5 ; poin;'}ter to top of free RAM1210 ;1220 FR1 = $E0 ; Fltg Pt Register 1, scratch1230 ;1240 STATUSOK = 1 ; I/O was good1250 STATU;(}SEOF = $88 ; reached an end-of-file1260 ;1270 HATABS = $31A1280 ;1290 HIGH = $100 ; divisor for high byte1300 LOW = $FF ;)}; mask for low byte1310 ;1320 .PAGE "The installation routine"1330 ;====== CHANGE NEXT LINE TO SUIT YOUR MEMORY ======13;*}40 *= $30001350 ; This first routine is simply1360 ; used to connect the driver1370 ; to Atari's handler address1380 ; ;+}table.1390 ;1400 LOADANDGO1410 LDX #0 ; We begin at start of table1420 SEARCHING1430 LDA HATABS,X ; Check device name;,}1440 BEQ EMPTYFOUND ; Found last one1450 CMP #'M' ; Already have M: ?1460 BEQ MINSTALLED ; Yes, don't reinstall1470 IN;-}X1480 INX1490 INX ; Point to next entry1500 BNE SEARCHING ; and keep looking1510 RTS ; Huh? Impossible!!!1520 ;1530;.} ; We found the current end of the1540 ; table...so extend it.1550 ;1560 EMPTYFOUND1570 LDA #'M' ; Our device name, "M:";/}1580 STA HATABS,X ; is first byte of entry1590 LDA #MDRIVER&LOW1600 STA HATABS+1,X ; LSB of driver addr1610 LDA #MDRI;0}VER/HIGH1620 STA HATABS+2,X ; and MSB of addr1630 LDA #01640 STA HATABS+3,X ; A new end for the table1650 ;1660 ; now;1} change LOMEM so BASIC won't1670 ; overwrite us.1680 ;1690 MINSTALLED1700 LDA #DRIVERTOP&LOW1710 STA MEMLO ; LSB of to;2}p addr1720 LDA #DRIVERTOP/HIGH1730 STA MEMLO+1 ; and MSB therof1740 ;1750 ; and that's all we have to do!1760 ;1770 ;3}RTS1780 ;1790 ;1800 ;;;;;;;;;;;;;;;;;;;;;;;;;;;1810 ;1820 ; This entry point is provided1830 ; so that BASIC can reconn;4}ect1840 ; the driver via a USR(RECONNECT)1850 ;1860 RECONNECT1870 PLA1880 BEQ LOADANDGO ; No parameters, I hope1890 ;5}TAY1900 PULLTHEM1910 PLA1920 PLA ; get rid of a parameter1930 DEY1940 BNE PULLTHEM ; and pull another1950 BEQ LOAD;6}ANDGO ; go reconnect1960 ;1970 .PAGE "The driver itself"1980 ;1990 ; Recall that all drivers must2000 ; be connected to;7} OS through2010 ; a driver routines address table.2020 ;2030 MDRIVER2040 .WORD MOPEN-1 ; The addresses must2050 .WORD ;8}MCLOSE-1 ; ...be given in this2060 .WORD MGETB-1 ; ...order and must2070 .WORD MPUTB-1 ; ...be one (1) less2080 .WORD M;9}STATUS-1 ; ...than the actual2090 .WORD MXIO-1 ; ...address2100 JMP MINIT ; This is for safety only2110 ;2120 ; For man;:}y drivers, some of these2130 ; routines are not needed, and2140 ; can effectively be null routines2150 ;2160 ; A null rou;;}tine should return2170 ; a one (1) in the Y-register2180 ; to indicate success.2190 ;2200 MXIO2210 MINIT2220 LDY #1 ; ;<}success2230 RTS2240 ;2250 ; If a routine is omitted because2260 ; it is illegal (reading from a2270 ; printer, etc.), s;=}imply pointing2280 ; to an RTS is adequate, since2290 ; Atari OS preloads Y with a2300 ; 'Function Not Implemented' error;>}2310 ; return code.2320 ;2330 .PAGE "The driver function routines"2340 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2350 ;2360 ; Now;?} we begin the code for the2370 ; routines that do the actual2380 ; work2390 ;2400 MOPEN2410 LDA ICAUX1,X ; Check type o;@}f open2420 AND #OPOUT ; Open for output?2430 BEQ OPENFORREAD ; No...assume for input2440 LDA MEMTOP2450 STA MSTART ; ;A}We start storing2460 LDY MEMTOP+1 ; ...the bytes2470 DEY ; ...one page below2480 STY MSTART+1 ; the supposed top of mem;B}2490 ;2500 ; now we join up with mode 4 open2510 ;2520 OPENFORREAD2530 LDA MSTART ; simply move the2540 STA MCURRENT ;C}; ...start pointer2550 LDA MSTART+1 ; ...to the current2560 STA MCURRENT+1 ; ...pointer, both bytes2570 ;2580 LDY #STA;D}TUSOK2590 RTS ; we don't acknowledge failure2600 ;2610 ;2620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2630 ;2640 ; the routine ;E}for CLOSE of M:2650 ;2660 MCLOSE2670 LDA ICAUX1,X ; check mode of open2680 AND #OPOUT ; was for output?2690 BEQ MCLRE;F}AD ; no...close input 'file'2700 ;2710 LDA MCURRENT ; we establish our2720 STA MSTOP ; ...limit so that2730 LDA MCURRE;G}NT+1 ; ...next use can't2740 STA MSTOP+1 ; ...go too far2750 ;2760 MCLREAD2770 LDY #STATUSOK2780 RTS ; and guaranteed;H} to be ok2790 ;2800 ;2810 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2820 ;2830 ; This routine puts one byte2840 ; to the memory for;I} later2850 ; retrieval.2860 ;2870 MPUTB2880 PHA ; save the byte to be PUT2890 JSR MOVECURRENT ; get ptr to zero page2;J}900 PLA ; the byte again2910 LDY #02920 STA (FR1),Y ; put the byte, indirectly2930 JSR DECCURRENT ; point to nxt byte;K}2940 RTS ; that's all2950 ;2960 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2970 ;2980 ; routine to get a byte put2990 ; in memory bef;L}ore.3000 ;3010 MGETB3020 JSR MSTATUS ; any more bytes?3030 BCS MGETRTS ; no...error3040 LDY #03050 LDA (FR1),Y ; ye;M}s...get a byte3060 JSR DECCURRENT ; and point to next byte3070 MGETRTS3080 RTS3090 ;3100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;N};;3110 ;3120 ; check the status of the driver3130 ;3140 ; this routine is only valid3150 ; when READing the 'file'...31;O}60 ; "M:" never gets errors when3170 ; writing.3180 ;3190 MSTATUS3200 JSR MOVECURRENT ; current ptr to zero page3210 C;P}MP MSTOP ; any more bytes to get?3220 BNE MSTOK ; yes3230 CPY MSTOP+1 ; double chk3240 BNE MSTOK ; yes, again3250 LDY;Q} #STATUSEOF ; oops...3260 SEC ; no more bytes3270 RTS3280 ;3290 MSTOK3300 LDY #STATUSOK ; all is okay3310 CLC ; fla;R}g for MGETB3320 RTS3330 .PAGE "Miscellaneous subroutines"3340 ;3350 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3360 ;3370 ; final;S}ly, we have a couple of3380 ; short and simple routines to3390 ; manipulate MCURRENT, the ptr3400 ; to the currently acces;T}sed byte3410 ;3420 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3430 ;3440 ; MOVECURRENT simply moves3450 ; MCURRENT to the floating;U}3460 ; point register, FR1, in3470 ; zero page. FR1 is always3480 ; safe to use except in the3490 ; middle of an expr;V}ession.3500 ;3510 MOVECURRENT3520 LDA MCURRENT3530 STA FR1 ; notice that we use3540 LDY MCURRENT+1 ; both the A and3;W}550 STY FR1+1 ; Y registers...this3560 RTS ; is for MSTATUS use3570 ;3580 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3590 ;3600 ;;X} DECCURRENT simply does a two3610 ; byte decrement of the MCURRENT3620 ; pointer and returns with the3630 ; Y register ;Y}indicating OK status.3640 ; NOTE that the A register is3650 ; left undisturbed.3660 ;3670 DECCURRENT3680 LDY MCURRENT ;Z}; check LSB's value3690 BNE DECLOW ; if non-zero, MSB is ok3700 DEC MCURRENT+1 ; if zero, need to bump MSB3710 DECLOW37;[}20 DEC MCURRENT ; now bump the LSB3730 LDY #STATUSOK ; as promised3740 RTS3750 .PAGE "RAM usage and clean up"3760 ;3;\}770 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3780 ;3790 ; END OF CODE3800 ;3810 ;3820 ; Now we define our storage3830 ; locations.;]}3840 ;3850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3860 ;3870 ;3880 ; MCURRENT holds the pointer to3890 ; the next byte to be PUT;^} or GET3900 MCURRENT .WORD 03910 ;3920 ; MSTOP is set by CLOSE to point3930 ; to the last byte PUT, so GET3940 ; won't t;_}ry to go past the end3950 ; of data.3960 MSTOP .WORD 03970 ;3980 ; MSTART is derived from MEMTOP3990 ; and points to the;`} first byte4000 ; stored. The bytes are stored4010 ; in descending addresses until4020 ; MSTOP is set by CLOSE.4030 MSTA;a}RT .WORD 04040 ;4050 ; DRIVERTOP becomes the new4060 ; contents of MEMLO4070 DRIVERTOP = *+$FF&$FF004080 ; (sets to next;b} page boundary)4090 ;4100 ;4110 ; The following is how you make4120 ; a LOAD-AND-GO file under4130 ; Atari's DOS 24140 ;c};4150 *= $2E04160 .WORD LOADANDGO4170 ;4180 ;4190 .END4120 ; a LOAD-AND-GO file under4130 ; Atari's DOS 24140 8B)AIOMAC.LIB -- OSS system I/O macrosAA Support MacrosA 10IOCB2 AYou must include SYSEQU.M65 ahead of th?e}is!!AX;$6X; These macros are called by the actual I/O macros.9X; to perform the rudimentary register load functions.?f}8X;BX;LX; MACRO: @CHVX;`6X; Loads IOCB number (parameter 1) into X register.jX;t 7 then a memory location1X; is assumed to?h} contain the channel number.X; @CH   Q T?T?T?T?>  $> (X;2X;<X; MAC?i}RO: @CVFX;P:X; Loads Constant or Value into accumultor (A-register)ZX;d+X; If value of parameter 1 is 0-255, @CVn+X; ?j}assumes it's an (immediate) constant.xX;'X; Otherwise the value is assumed to+X; be a memory location (non-zero page).?k}X;X;X; @CV   Q> Q X;X;X;X;"X; MACRO: @FL,X;65X; @FL is used to e?l}stablish a filespec (file name)@X;J-X; If a literal string is passed, @FL willT'X; generate the string in line, jump^&X;?m} around it, and place its addressh/X; in the IOCB pointed to by the X-register.rX;|(X; If a non-zero page label is passed?n}*X; the MACRO assumes it to be the label.X; of a valid filespec and uses it instead.X;X;X; @FL   ?o} !   @F = Q>4@F PICBADR9 Q>5@FPICBADR9 Q>4  PICBADR9& Q>5 0PICBADR9:D?p}NA XIO macroAXX;bX; MACRO: XIOlX;v/X; FORM: XIO cmd,ch[,aux1,aux2][,filespec]X;%X; ch is given as in the?q} @CH macro3X; cmd, aux1, aux2 are given as in the @CV macro+X; filespec is given as in the @FL macroX;5X; performs f?r}amiliar XIO operations with/for OS/A+X;/X; If aux1 is given, aux2 must also be given8X; If aux1 and aux2 are omitted, ?s}they are set to zero1X; If the filespec is omitted, "S:" is assumedX; XIO  3 % AXIO: wrong number o?t}f argumentsA  @CH   @CV *PICCOM9;; COMMAND4  > @CV H PICAUX19R @CV \ PICAUX29fp?u}Q>z PICAUX19 PICAUX29 3 @FL AS:A @@IO @FL @@@IO: CIOA ?v} OPEN macroAX; X; MACRO: OPEN X; (X; FORM: OPEN ch,aux1,aux2,filespec$ X;. %X; ch is given as in the @CH macro8 1?w}X; aux1 and aux2 are given as in the @CV macroB +X; filespec is given as in the @FL macroL X;V 1X; will attempt to open the ?x}given file name on` /X; the given channel, using the open "modes"j X; specified by aux1 and aux2t X;~ OPEN   &?y} AOPEN: wrong number of argumentsA    XIO COPN= = = =   XIO COPN= = = =    ?z} A BGET and BPUT macrosA X; X; MACROS: BGET and BPUT X; X; FORM: BGET ch,buf,len X; BPUT ch,buf,le?{}n( X;2 %X; ch is given as in the @CH macro< .X; len is ALWAYS assumed to be an immediateF 1X; and actual value...never a m?|}emory addressP /X; buf must be the address of an appropriateZ X; buffer in memoryd X;n +X; puts or gets length bytes to/f?}}rom thex 0X; specified buffer, uses binary read/write X; X; X; first: a common macro X; @GP @CH  Q> ?~} PICCOM9 Q>4  PICBADR9 Q>5  PICBADR9 Q>4  PICBLEN9 Q>5  PICBLEN9"  CIO, 6 X;@ B?}GET J  T ' ABGET: wrong number of parametersA^ h @GP = = =CGBINRr |  X; BPUT   ' AB?}PUT: wrong number of parametersA  @GP = = =CPBINR   X; A PRINT macroA X; X; MACRO: PRINT ?}X; (X; FORM: PRINT ch[,buffer[,length]] X; !X; ch is as given in @CH macro& (X; if no buffer, prints just a RETURN0 %X;?} if no length given, 255 assumed: X;D 8X; used to print text. To print text without RETURN,N -X; length must be given. See?} OS/A+ manualX X;b 2X; EXCEPTION: second parameter may be a literall .X; string (e.g., PRINT 0,"test"), in whichv -X; case?} the length (if given) is ignored. X; PRINT  3  ( APRINT: wrong number of parametersA    ?}  !   @IO = @GP =@IO= =CPTXTR    @GP = ==CPTXTR  @GP = ?}= =CPTXTR  * 4 ! > @IO H @GP =@IO==CPTXTRR \ f p X;z A INPUT macroA X; X; MACRO:?} INPUT X; X; FORM: INPUT ch,buf,len X; %X; ch is given as in the @CH macro )X; buf MUST be a proper buffer address?} 6X; len may be omitted, in which case 255 is assumed X; ,X; gets a line of text input to the given 'X; buffer, maximu?}m of length bytes X; INPUT  3 ( AINPUT: wrong number of parametersA$  .@GP = ==?}CGTXTR8B@GP = = =CGTXTRLV`jA CLOSE macroAtX;~X; MACRO: CLOSEX;X; FORM: CLOSE ch?}X;%X; ch is given as in the @CH macroX;X; closes channel chX; CLOSE   ( ACLOSE: wrong number of par?}ametersA @CH  Q>CCLOSE  PICCOM9 CIO(2X;<-X;;;;;;;;;;; END OF IOMAC.LIB ;;;;;;;;;;;;FX; of par<vs